//#include "StdAfx.h"
#include "JpegDecoder16.h"

//#include "jpeglib.h"


#define INCLUDE_CSTDIO
#define INCLUDE_CSETJMP
#include "dcmtk/ofstd/ofstdinc.h"

// These two macros are re-defined in the IJG header files.
// We undefine them here and hope that IJG's configure has
// come to the same conclusion that we have...
#ifdef HAVE_STDLIB_H
#undef HAVE_STDLIB_H
#endif
#ifdef HAVE_STDDEF_H
#undef HAVE_STDDEF_H
#endif


BEGIN_EXTERN_C
//#undef boolean
#define boolean ijg_boolean
#include "jpeglib16.h"
#include "jerror16.h"
#include "jpegint16.h"
#undef boolean
END_EXTERN_C

#include "jpegDecodeProc.h"
JpegDecoder16::JpegDecoder16(void)
{
}

JpegDecoder16::JpegDecoder16(void * inputData, int length, void * outputData)
: JpegDecoderXX(inputData, length, outputData)
{
	initJpeg();
}

JpegDecoder16::~JpegDecoder16(void)
{ 
}

void JpegDecoder16::decompress(){	
	jpegSrcManager->next_input_byte = (const JOCTET *)inputData;
	jpegSrcManager->bytes_in_buffer = length;		
	if (suspension < 2)
	{
		if (JPEG_SUSPENDED == jpeg_read_header(jpegInfo, TRUE))
		{
			suspension = 1;
			return ;
		}

	}
	int bufsize;
	int rowsize;
	if (suspension < 3)
	{
		if (FALSE == jpeg_start_decompress(jpegInfo))
		{
			suspension = 2;
			return;
		}
		bufsize = jpegInfo->output_width * jpegInfo->output_components; // number of JSAMPLEs per row
		rowsize = bufsize * sizeof(JSAMPLE); // number of bytes per row
		if(this->bufsize < bufsize){
			buffer = (*jpegInfo->mem->alloc_sarray)((j_common_ptr)jpegInfo, JPOOL_IMAGE, bufsize, 1);
			if (buffer == NULL) 
				return;
			this->buffer = buffer;
		}
		this->bufsize = bufsize;
	}
	else
	{
		bufsize = jpegInfo->output_width * jpegInfo->output_components;
		rowsize = bufsize * sizeof(JSAMPLE);
		buffer = this->buffer;
	}	

	this->bufsize = bufsize;	
	while (jpegInfo->output_scanline < jpegInfo->output_height){
		//QCoreApplication::processEvents();
		if (0 == jpeg_read_scanlines(jpegInfo, (JSAMPARRAY)buffer, 1))
		{
			suspension = 3;
			return;
		}		
		memcpy((char *)outputData + (jpegInfo->output_scanline - 1) * rowsize, * (JSAMPARRAY)buffer, rowsize);			
	}	
	if (FALSE == jpeg_finish_decompress(jpegInfo))
	{
		suspension = 4;
		return;
	}

}

void JpegDecoder16::initJpeg(){	
	suspension = 0;
	jpegSrcManager = new jpeg_source_mgr;
	jpegErr = new jpeg_error_mgr;
	jpegInfo = new jpeg_decompress_struct;							
	jpegInfo->err = jpeg_std_error(jpegErr);	
	jpegInfo->err->trace_level = 0;
	jpegInfo->err->num_warnings = 2;	
	jpegInfo->err->emit_message = (void (*)(j_common_ptr,int)) jpeg_emit_message;
	jpegErr->error_exit = my_error_exit;		
	jpegSrcManager->init_source = JpegInitSource;
	jpegSrcManager->fill_input_buffer = (ijg_boolean (__cdecl *)(j_decompress_ptr))JpegFillInputBuffer;
	jpegSrcManager->skip_input_data = JpegSkipInputData;
	jpegSrcManager->resync_to_restart = jpeg_resync_to_restart;
	jpegSrcManager->term_source = JpegTermSource;
	jpeg_create_decompress(jpegInfo);	
	jpegInfo->src = jpegSrcManager;	
}

void JpegDecoder16::destroyJpeg(){		
	if(jpegInfo != NULL){
		//jpegInfo->mem->free_pool((j_common_ptr) jpegInfo, JPOOL_IMAGE);
		jpeg_destroy_decompress(jpegInfo);
		delete jpegErr;
		delete jpegInfo;	
		delete jpegSrcManager;
		jpegInfo = NULL;
	}	
}